package org.example.novelcrawler.util;

import org.jsoup.nodes.Document;
import org.seimicrawler.xpath.JXDocument;
import org.seimicrawler.xpath.JXNode;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

public class XPathQueryHelper {
    /**
     * 查询单个元素
     */
    public static JXNode selectOne(Document doc, String xpath) {
        JXDocument jxDoc = JXDocument.create(doc.getAllElements());
        List<JXNode> nodes = jxDoc.selN(xpath);
        return nodes.isEmpty() ? null : nodes.get(0);
    }

    /**
     * 查询多个元素
     */
    public static List<JXNode> selectMany(Document doc, String xpath) {
        JXDocument jxDoc = JXDocument.create(doc.getAllElements());
        return jxDoc.selN(xpath);
    }

    /**
     * 查询文本内容（自动处理空值）
     */
    public static String selectText(Document doc, String xpath) {
        try {
            JXDocument jxDoc = JXDocument.create(doc.getAllElements());
            return jxDoc.sel(xpath).toString();
        } catch (Exception e) {
            return "";
        }
    }

    /**
     * 查询属性值
     */
    public static String selectAttribute(Document doc, String xpath, String attribute) {
        return selectText(doc, xpath + "/@" + attribute);
    }

    /**
     * 查询并转换为绝对URL
     */
    public static String selectAbsoluteUrl(Document doc, String xpath, String baseUrl) {
        String href = selectAttribute(doc, xpath, "href");
        if (href == null || href.isEmpty()) return "";

        try {
            java.net.URL base = new java.net.URL(baseUrl);
            java.net.URL absolute = new java.net.URL(base, href);
            return absolute.toString();
        } catch (Exception e) {
            return href;
        }
    }

    /**
     * 查询并处理结果
     */
    public static <T> List<T> selectAndProcess(Document doc, String xpath,
                                               Function<JXNode, T> processor) {
        List<JXNode> nodes = selectMany(doc, xpath);
        List<T> results = new ArrayList<>();

        for (JXNode node : nodes) {
            try {
                T result = processor.apply(node);
                if (result != null) {
                    results.add(result);
                }
            } catch (Exception e) {
                System.err.println("处理节点失败: " + e.getMessage());
            }
        }

        return results;
    }

    /**
     * 安全查询：带默认值
     */
    public static <T> T selectSafely(Document doc, String xpath,
                                     Function<String, T> converter,
                                     T defaultValue) {
        try {
            String value = selectText(doc, xpath);
            return value != null && !value.isEmpty() ? converter.apply(value) : defaultValue;
        } catch (Exception e) {
            return defaultValue;
        }
    }

    /**
     * 检查元素是否存在
     */
    public static boolean exists(Document doc, String xpath) {
        return !selectMany(doc, xpath).isEmpty();
    }

    /**
     * 获取元素的完整XPath（调试用）
     */
    public static String getElementXPath(org.jsoup.nodes.Element element) {
        if (element == null) return "";

        StringBuilder path = new StringBuilder();
        org.jsoup.nodes.Element current = element;

        while (current != null && !current.tagName().equals("#root")) {
            String part = current.tagName();

            // 添加索引
            org.jsoup.nodes.Element parent = current.parent();
            if (parent != null) {
                int index = 1;
                for (org.jsoup.nodes.Element sibling : parent.children()) {
                    if (sibling == current) break;
                    if (sibling.tagName().equals(current.tagName())) index++;
                }
                if (parent.children().size() > 1) {
                    part += "[" + index + "]";
                }
            }

            if (path.length() > 0) {
                path.insert(0, "/");
            }
            path.insert(0, part);

            current = parent;
        }

        return "/" + path.toString();
    }

}
